﻿using namespace std;
#include<iostream>
//===============================================================================================
//===============================================================================================
//===============================================================================================
//===============================================================================================
// ==================================C++基础语法
//===================================传值返回和引用返回

//int func1()
//{
//	int a = 0;
//	return a;
//}
//// 传值返回所返回的是当前对象的拷贝
//
//int& func2()
//{
//	int b = 0;
//	return b;
//}
////引用返回返回的是对象本身,
////返回对象是一个局部变量,出了作用域便会被销毁,
////所以不可使用引用返回
////出了作用域,引用对象还在,才可以引用返回
//
//int main()
//{
//	//a是func1(传值返回)临时对象的别名
//	const int& ao = func1();
//	return 0;
//}
//
//
////========================================匿名对象
//
//int main()
//{
//	int(3);
//	//匿名对象的生命周期在当前这一行
//	return 0;
//}
//
////=========================================内存管理
//int main()
//{
//	int* p1 = new int(6);
//	int* p2 = new int[6];
//	//圆括号就是开辟空间并且赋值
//	//方括号就是在堆上分配了一个可以存储6个整数的数组
//
//	int* p3 = new int[6] {1, 2, 3};//初始化
//
//	delete p1;
//	//delete是释放内存
//	return 0;
//}
////operator new+malloc的封装+构造函数
////operator delete +析构函数
//
////=========================================模板
//template<class T1, class T2>
//auto Add(const T1& left, const T2& right){
//	return left + right;
//}
//int main(){
//	Add<int, double>(1, 2.2);
//	return 0;
//}
//
////===============================================================================================
////===============================================================================================
////===============================================================================================
////========================================C98默认成员函数==========================================
////===================================构造函数 析构函数 拷贝构造函数
////构造函数和析构函数属于六大默认成员函数,在使用此类实例化一个对象时会并进行相关操作时会自动调用
////六大默认成员函数:  C98:默认构造函数,拷贝构造函数,析构函数,拷贝赋值运算符  C11:移动构造函数,移动赋值运算符 
//template<class T>
//class Date
//{
//public:
//	//构造函数
//	Date(T day = 1, T year = 2, T month = 3)
//		:_day(day), _year(year) {
//		_month = month;
//	}
//	//// 默认构造函数  
//	//Date() : _date(T()), _year(T()), _month(T()) {}
//	//// 带参数的构造函数，参数有默认值  
//	//Date(T date = 1970, T year = 1, T month = 1)
//	//	: _date(date), _year(year), _month(month) {}
//
//	//涉及动态内存管理的才要使用析构函数进行内存清理
//	~Date(){}
//private:
//	T _day;
//	T _year;
//	T _month;
//};
//
//int main()
//{
//	Date<int> in;
//	return 0;
//}
//
////如果我们不写构造/析构函数(默认成员函数),编译器也会自动生成
////编译器会如何生成默认构造函数
////对于内置类型成员变量,编译器会给予它们内存中存在的任意值
////对于自定义类型成员变量,编译器会调用其✦默认构造函数✦
////默认构造函数=不传参就可以调用的函数(无参,全缺省,我们没写编译器自动生成的,三者仅可存在一个)
//
////===================================拷贝构造(拷贝初始化)函数
////如果没有管理资源,一般不用写拷贝构造,默认生成的拷贝构造就可以了,就不如上面的Date
////如果是自定义成员,内置类型成员没有指向资源,也类似默认生成的拷贝构造(浅拷贝)就可以
////一般情况下,不需要写析构函数同时也不要写拷贝构造函数
////如果内部有相关管理资源的指针,需要显示写析构函数,通常需要显示写拷贝构造完成深拷贝
//class Date2
//{
//public:
//	//拷贝构造函数,属于构造函数,也是自动调用的
//	Date2(Date2& d)//规定参数列表必须使用引用
//	{//否则会发生无穷拷贝
//		this->_month = d._month;
//		_day = d._day;
//		_year = d._year;
//	}//Date d1(d):d是已经构造过了,d1是被拷贝构造的对象
//private:
//	int _day;
//	int _year;
//	int _month;
//};
//
////===================================拷贝赋值运算符operator=
//class Date1
//{
//public:
//	Date1& operator=(const Date1& d){
//		day = d.day;
//		month = d.month;
//		year = d.year;
//		return *this;
//	}
//private:
//	int day;
//	int year;
//	int month;
//};

//================================================================================================
//================================================================================================
//================================================================================================
//================================================================================================
//========================================继承
//class Base {
//protected:
//	int protectedMember;
//private:
//	int privateMember;
//};
//
//class Derived : public Base {
//public:
//	void accessProtectedMember() {
//		// 派生类成员函数可以访问基类的protected成员  
//		protectedMember = 10;
//	}
//};
//
//int main() {
//	Derived d;
//	// d.protectedMember; // 错误：派生类对象不能直接访问protected成员  
//	d.accessProtectedMember(); // 正确：通过派生类成员函数间接访问  
//	return 0;
//}

//base类中protected成员在派生类中可访问,但不可在int main函数中直接访问
//base类中private成员在派生类中不可见 

//=======================================组合
class OS {
protected:
	string base = "Linux";
};
class DOS {
protected:
	string shell = "Windows";
	OS _o;
};
//组合就是一个类中有另外一个类

//=======================================多态
//不同的对象去做相同的事情得到不同的结果
//多态条件 1.虚函数重写 2.base类指针或者引用调用函数
class Person {
public:
	virtual void BuyTicket() {
		cout << "全价票" << endl;
	}
};
class Student :public Person {
public:
	virtual void BuyTicket() {
		cout << "半价票" << endl;
	}
};

//base类指针或引用
void fun(Person& d) {
	d.BuyTicket();
}
void fun(Person* d) {
	d->BuyTicket();
}
int main()
{
	Person a; a.BuyTicket();
	Student h; h.BuyTicket();
	fun(a); fun(h); 
	return 0;
}
//析构函数是否建议设计成虚函数
//析构函数一定设计成析构函数,只有这样,派生类才可以构成重写(针对不同类特殊化处理)
//派生类的重写函数可加virtual也可以不加

//========================================纯虚函数
class Base {
public:
	// 纯虚函数声明  
	virtual void pureVirtualFunction() = 0;
};
class Derived {
	virtual void pureVirtualFunction(){}
};





